package cevent.source.cloudcenter.template.generator;/**
 * Created by Cevent on 2021/3/20.
 */

import cevent.source.cloudcenter.template.util.DataBaseUtil;
import cevent.source.cloudcenter.template.util.FieldUtil;
import cevent.source.cloudcenter.template.util.FreemarkerUtil;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.util.*;

/**
 * @author cevent
 * @description 代码生成器主函数:dto/service/controller
 * @date 2021/3/20 16:41
 */
public class GeneratorApplication {
    //生成的模块目标路径节点
    static String PARENT_DIR="cevent-source-cloudcenter";
    static String MODULE="business-core";
    static String MODULE_NAME="business";
    //static String MODULE="source-center";

    /*static String MODULE="system-manager";
    static String MODULE_NAME="system";*/
    static String COMMON="server-common";
    static String COMMON_NAME="server";
    //1.获取ftl文件路径--> origin path
    //static String originPath="cevent\\source\\cloudcenter\\business\\controller\\admin\\";
    //2.生成的文件路径--> target path
    static String targetDtoPath=PARENT_DIR+"\\"+COMMON+"\\src\\main\\java\\cevent\\source\\cloudcenter\\"+COMMON_NAME+"\\dto\\";
    static String targetServicePath=PARENT_DIR+"\\"+COMMON+"\\src\\main\\java\\cevent\\source\\cloudcenter\\"+COMMON_NAME+"\\service\\";
    static String targetControllerPath=PARENT_DIR+"\\"+MODULE+"\\src\\main\\java\\cevent\\source\\cloudcenter\\"+MODULE_NAME+"\\controller\\admin\\";

    //3.直接读取server-generator-config文件，这里，如果我们的项目不在主dir文件夹，需要在前缀声明-> 父文件夹位置
    static String generatorConfig=PARENT_DIR+"\\"+COMMON+"\\src\\main\\resources\\generator\\generatorConfig.xml";

    public static void main(String[] args) throws Exception {

        //1.1只生成配置文件中第一个table节点
        File file=new File(generatorConfig);
        //1.2读取xml到document文件中
        SAXReader saxReader=new SAXReader();
        Document document=saxReader.read(file);
        //1.3读取xml文件的根节点
        Element rootElement=document.getRootElement();
        //1.4读取context节点
        Element contextElement=rootElement.element("context");
        //1.5定义element作为遍历table对象
        Element tableElement;
        //1.6获取第一个table节点
        tableElement=contextElement.elementIterator("table").next();
        //对应配置文件中的：domainObjectName="Section"
        String Domain=tableElement.attributeValue("domainObjectName");
        //转换小写
        String domain=Domain.substring(0,1).toLowerCase()+Domain.substring(1);
        //表名
        String tableName=tableElement.attributeValue("tableName");
        //获取表注释
        String tableNameCN=DataBaseUtil.getTableComment(tableName);
        System.out.println("表名："+tableElement.attributeValue("tableName"));
        System.out.println("表构建的Domain："+tableElement.attributeValue("domainObjectName"));

        //2.获取所有列信息
        List<FieldUtil> fieldUtilList= DataBaseUtil.getColumnByTableName(tableName);
        //根据类信息，获取所有的set类型集合，typeSet用于ftl中获取java类型集合
        Set<String> typeSet=getJavaTypes(fieldUtilList);
        Map<String,Object> map=new HashMap<>();
        map.put("Domain",Domain);
        map.put("domain",domain);
        map.put("tableNameCN",tableNameCN);
        map.put("module",MODULE);
        map.put("fieldUtilList",fieldUtilList);
        map.put("typeSet",typeSet);

        //3.service初始化，指定使用的模板名称-->读取
        FreemarkerUtil.initConfig("service.ftl");
        //将map传递到模板,指定生成文件的：路径+文件名-->生成
        FreemarkerUtil.generator(targetServicePath+Domain+"Service.java",map);

        //4.controller初始化
        FreemarkerUtil.initConfig("controller.ftl");
        FreemarkerUtil.generator(targetControllerPath+Domain+"Controller.java",map);
        //5.dto初始化
        FreemarkerUtil.initConfig("dto.ftl");
        FreemarkerUtil.generator(targetDtoPath+Domain+"Dto.java",map);
    }

    /*获取所有的java类型，set去重*/
    private static Set<String> getJavaTypes(List<FieldUtil> fieldUtilList){
        Set<String> set=new HashSet<>();
        for (int i=0;i<fieldUtilList.size();i++){
            FieldUtil fieldUtil=fieldUtilList.get(i);
            set.add(fieldUtil.getJavaType());
        }
        return set;
    }
}
